﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Input;

namespace InstaMe
{

    public partial class ImageUserControl : UserControl
    {
        public event EventHandler ImageLoaded;
        public event EventHandler ImageLoadFail;

        private bool isLoadFail;
        private BitmapImage mDefaultSource;
        private BitmapImage mSource;

        public ImageUserControl()
        {
            InitializeComponent();
            Image.DataContext = this;
            mDefaultSource = null;
            ImageLoaded = null;
            ImageLoadFail = null;
            isLoadFail = true;
            RefreshCommand = new RefreshViewCommand(this.UpdateImage);
        }

        private void CreateEllipseGeomety()
        { 
            if (IsClip && !Double.IsNaN(Image.Width) && !Double.IsNaN(Image.Height) && Image.Clip == null)
            {
                EllipseGeometry ellipseGeometry = new EllipseGeometry();
                double radiusX = Image.Width / 2;
                double radiusY = Image.Height / 2;
                ellipseGeometry.Center = new Point(radiusX, radiusY);
                ellipseGeometry.RadiusX = radiusX;
                ellipseGeometry.RadiusY = radiusY;
                Image.Clip = ellipseGeometry;
            }
        }

        public ICommand RefreshCommand
        {
            get;
            private set;
        }

        public bool hasLoadedSuccess()
        {
            return !isLoadFail;
        }

        public void UpdateImage()
        {
            //BitmapImage iImage = DownloadManager.getInstance().GetImage(Source, ImageDownloadType, mDownloadListener);
            //if (iImage != null)
            //{
            //    SetSource(iImage);
            //    if (ImageLoaded != null)
            //    {
            //        ImageLoaded(this, EventArgs.Empty);
            //    }
            //}
            //else
            //{
            //    SetSource(mDefaultSource);
            //}
        }

        private DownloadManager.DownloadType _ImageDownloadType = DownloadManager.DownloadType.DOWNLOAD_CACHE;
        public DownloadManager.DownloadType ImageDownloadType
        {
            get
            {
                return _ImageDownloadType;
            }
            set
            {
                _ImageDownloadType = value;
            }
        }

        //==================================================DependencyProperty=========================================
        public static readonly DependencyProperty DefaultSourceProperty = DependencyProperty.Register(
                                          "DefaultSource",
                                          typeof(String),
                                          typeof(ImageUserControl),
                                          new PropertyMetadata(default(String), OnDefaultSourceChanged));

        private static void OnDefaultSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is ImageUserControl)
            {
                string iDefaultUrl = e.NewValue as String;
                // Set Default source to Image
                ImageUserControl iUserControl = (ImageUserControl)d;
                iUserControl.OnDefaultSourceChanged();                
            }
        }
        
        public string DefaultSource
        {
            get
            {
                return GetValue(DefaultSourceProperty) as String;
            }
            set
            {                
                SetValue(DefaultSourceProperty, value);
            }
        }

        public void OnDefaultSourceChanged()
        {
            mDefaultSource = new BitmapImage(new Uri(DefaultSource, UriKind.RelativeOrAbsolute));
            SetSource(mDefaultSource);
        }
        //=============================================================================================================
        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
                                          "Source",
                                          typeof(String),
                                          typeof(ImageUserControl),
                                          new PropertyMetadata(default(String), OnSourcePropertyChanged));

        private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ImageUserControl)d).OnSourceChanged();
        }

        public string Source
        {
            get
            {
                return GetValue(SourceProperty) as String;
            }
            set
            {
                SetValue(SourceProperty, value);
            }
        }

        private void OnSourceChanged()
        {
            BitmapImage iCacheImage = null;
            if (IsAutoLoadImage)
            {
                iCacheImage = DownloadManager.getInstance().GetImage(Source, ImageDownloadType, mDownloadListener);
            }
            else
            {
                iCacheImage = DownloadManager.getInstance().GetCacheImage(Source);
            }

            if (iCacheImage != null)
            {
                SetSource(iCacheImage);
                if (ImageLoaded != null)
                {
                    ImageLoaded(this, EventArgs.Empty);
                }
                isLoadFail = false;
            }
            else
            {
                SetSource(mDefaultSource);
                isLoadFail = true;
            }
        }
        //==================================================
        public static readonly DependencyProperty IsAutoLoadImageProperty = DependencyProperty.Register(
                                                        "IsAutoLoadImage",
                                                        typeof(bool),
                                                        typeof(ImageUserControl),
                                                        new PropertyMetadata(true));

        public bool IsAutoLoadImage
        {
            get
            {
                return (bool)GetValue(IsAutoLoadImageProperty);
            }
            set
            {
                SetValue(IsAutoLoadImageProperty, value);
            }
        }

        //==================================================
        public static readonly DependencyProperty StyleProperty = DependencyProperty.Register(
                                          "Style",
                                          typeof(Style),
                                          typeof(ImageUserControl),
                                          new PropertyMetadata(default(Style), OnStylePropertyChanged));

        private static void OnStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ImageUserControl)d).Image.Style = ((ImageUserControl)d).Style;
        }

        public Style Style
        {
            get
            {
                return GetValue(StyleProperty) as Style;
            }
            set
            {
                SetValue(StyleProperty, value);
            }
        }
        //==================================================
        private Stretch _stretch;
        public Stretch Stretch
        {
            get
            {
                return _stretch;
            }
            set
            {
                if (value != _stretch)
                {
                    _stretch = value;
                    this.Image.Stretch = value;
                }
            }
        }

        private bool _autoRefresh = false;
        public bool AutoRefresh
        {
            get
            {
                return _autoRefresh;
            }
            set
            {
                if (value != _autoRefresh)
                {
                    _autoRefresh = value;
                }
            }
        }

        private PageOrientation _pageOrientation = PageOrientation.PortraitUp;
        public PageOrientation PageOrientation
        {
            get
            {
                return _pageOrientation;
            }
            set
            {
                if (value != _pageOrientation)
                {
                    _pageOrientation = value;
                }
            }
        }

        private bool _isClip = false;
        public bool IsClip
        {
            get
            {
                return _isClip;
            }
            set
            {
                if (value != _isClip)
                {
                    _isClip = value;
                }
            }
        }
        //==================================================Method=========================================
        private void SetSource(BitmapImage source)
        {
            mSource = source;
            this.Image.Source = source;
        }

        public BitmapImage GetSource()
        { 
            return mSource;
        }
        //==================================================EventHandler=========================================
        public event EventHandler<ExceptionRoutedEventArgs> ImageFailed;
        private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            EventHandler<ExceptionRoutedEventArgs> handler = this.ImageFailed;
            if (handler != null)
            {
                handler(sender, e);
            }
        }

        public event EventHandler<RoutedEventArgs> ImageOpened;
        private void Image_ImageOpened(object sender, RoutedEventArgs e)
        {
            EventHandler<RoutedEventArgs> handler = this.ImageOpened;
            if (handler != null)
            {
                handler(sender, e);
            }
        }


        private void Image_Loaded(object sender, RoutedEventArgs e)
        {
            if (_autoRefresh)
            {
                OnSourceChanged();
            }
        }
/*****************************************************************************************/
/* Listener
/*****************************************************************************************/
        private void OnImageDownloadComplete(string aUrl, BitmapImage aImageData)
        {
            Dispatcher.BeginInvoke(() =>
            {
                if (aUrl == Source && aImageData != null)
                {
                    //this.Image.Source = null;
                    SetSource(aImageData);
                    if (ImageLoaded != null)
                    {
                        ImageLoaded(this, EventArgs.Empty);
                    }
                    isLoadFail = false;
                }
            });
        }

        private void OnImageDownloadError(string aUrl, int aErrorCode)
        {
            Dispatcher.BeginInvoke(() =>
            {
                if (Source == aUrl)
                {
                    if (ImageLoadFail != null)
                    {
                        ImageLoadFail(this, EventArgs.Empty);
                    }
                    isLoadFail = true;
                }
            });
        }

        private void Image_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            CreateEllipseGeomety();
        }
    }
}
